<template>
  <view class="u-table" :style="{ height: height ? height + 'px' : 'auto' }">
    <!-- 表头 -->
    <view v-if="showHeader" class="u-table-header" :class="{ 'u-table-sticky': fixedHeader }">
      <view class="u-table-row">
        <view
          v-for="(col, colIndex) in columns"
          :key="col.key"
          class="u-table-cell"
          :style="{ width: col.width ? addUnit(col.width) : 'auto', flex: col.width ? 'none' : 1 }"
          :class="[
            col.align ? 'u-text-' + col.align : '',
            headerCellClassName ? headerCellClassName(col) : '',
            col.fixed === 'left' ? 'u-table-fixed-left' : '',
            col.fixed === 'right' ? 'u-table-fixed-right' : ''
          ]"
          @click="handleHeaderClick(col)"
        >
					<!-- 复选框列 -->
					<view v-if="col.type === 'selection'">
					  <checkbox
							style="transform:scale(0.6)"
					    :checked="isSelectedAll()"
					    @click.stop="toggleSelectAll()"
					  />
					</view>
          {{ col.title }}
          <view v-if="col.sortable">
            {{ getSortIcon(col.key) }}
          </view>
        </view>
      </view>
    </view>

    <!-- 表体 -->
    <view class="u-table-body" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : 'none' }">
      <block v-if="data.length > 0">
        <template v-for="(row, index) in sortedData" :key="row[rowKey] || index">
          <view
            :class="[
              highlightCurrentRow && currentRow === row ? 'u-table-row-highlight' : '',
              stripe && index % 2 === 1 ? 'u-table-row-zebra' : ''
            ]"
          >
						<!-- 表格前 -->
						<view @click="handleRowClick(row)">
							<slot name="before" :row="row"></slot>
						</view>
            <view
							class="u-table-row"
							@click="handleRowClick(row)"
							:class="rowClassName ? rowClassName(row, index) : ''">
							<view
							  v-for="(col, colIndex) in columns"
							  :key="col.key"
							  class="u-table-cell"
							  :class="[
							    col.align ? 'u-text-' + col.align : '',
							    cellClassName ? cellClassName(row, col) : '',
							    col.fixed === 'left' ? 'u-table-fixed-left' : '',
							    col.fixed === 'right' ? 'u-table-fixed-right' : ''
							  ]"
							  :style="{ width: col.width ? addUnit(col.width) : 'auto', flex: col.width ? 'none' : 1 }"
							>
							  <!-- 复选框列 -->
							  <view v-if="col.type === 'selection'">
							    <checkbox
										style="transform:scale(0.6)"
							      :checked="isSelected(row)"
							      @click.stop="toggleSelect(row)"
							    />
							  </view>
							
							  <!-- 树形结构展开图标 -->
							  <view class="table-expand-td" v-else-if="col.type === 'expand' && row.children && row.children.length > 0" @click.stop="toggleExpand(row)">
							    {{ isExpanded(row) ? '▼' : '▶' }}
							  </view>
							  <!-- 默认插槽或文本 -->
							  <slot :name="col.key" :row="row">
							    {{ row[col.key] }}
							  </slot>
							</view>
							<!-- 操作按钮 -->
							<view class="operate-more main-flex" v-if="isOperateBtn ? isOperateBtn(row, index) : false" @click.stop="showOperate(row)">
								<!-- <uni-icons class="operate-more-icon" type="gear" size="32rpx" color="#ffffff"></uni-icons> -->
								<image v-if="isOperateArr.includes(row[rowKey])" src="/static/images/up.svg" class="operate-more-icon" ></image>
								<image v-else src="/static/images/down.svg" class="operate-more-icon" ></image>
							</view>
						</view>
						<!-- 表格后 -->
						<view @click="handleRowClick(row)">
							<slot name="after" :row="row"></slot>
						</view>
						<!-- 操作 -->
						<view v-show="isOperateArr.includes(row[rowKey])">
							<slot name="operate" :row="row"></slot>
						</view>
          </view>

          <!-- 子级渲染 -->
          <template v-if="isExpanded(row) && row[treeProps.children] && row[treeProps.children].length">
            <view
              v-for="child in row[treeProps.children]"
              :key="child[rowKey]"
              class="u-table-row-child"
            >
							<!-- 表格前 -->
							<view @click="handleRowClick(row)">
								<slot name="before" :row="row"></slot>
							</view>
              <view
								class="u-table-row"
								@click="handleRowClick(row)"
								:class="rowClassName ? rowClassName(row, index) : ''">
								<view
								  v-for="col in columns"
								  :key="col.key"
								  class="u-table-cell"
									:class="[
										col.align ? 'u-text-' + col.align : '',
										cellClassName ? cellClassName(row, col) : ''
									]"
								  :style="{ width: col.width ? addUnit(col.width) : 'auto', flex: col.width ? 'none' : 1 }"
								>
									<!-- 复选框列 -->
									<view v-if="col.type === 'selection'">
									  <checkbox
									    :checked="isSelected(child)"
									    @click.stop="toggleSelect(child)"
									  />
									</view>
									
								  <slot :name="col.key" :row="child">
								    {{ child[col.key] }}
								  </slot>
								</view>
							</view>
							<!-- 表格后 -->
							<view @click="handleRowClick(row)">
								<slot name="after" :row="row"></slot>
							</view>
							<!-- 操作 -->
							<slot name="operate" :row="row"></slot>
            </view>
          </template>
        </template>
      </block>
      <block v-else>
        <slot name="empty">
          <view class="u-table-empty">暂无数据</view>
        </slot>
      </block>
    </view>
  </view>
</template>

<script>
import { ref, watch, computed } from 'vue'
import { addUnit } from 'uview-plus'

export default {
  name: 'ty-table-tree',
  props: {
    data: {
      type: Array,
      required: true,
      default: () => []
    },
    columns: {
      type: Array,
      required: true,
      default: () => [],
      validator: cols =>
        cols.every(col =>
          ['default', 'selection', 'expand'].includes(col.type || 'default')
        )
    },
    stripe: {
      type: Boolean,
      default: false
    },
    border: {
      type: Boolean,
      default: false
    },
    height: {
      type: [String, Number],
      default: null
    },
    maxHeight: {
      type: [String, Number],
      default: null
    },
    showHeader: {
      type: Boolean,
      default: true
    },
    highlightCurrentRow: {
      type: Boolean,
      default: false
    },
    rowKey: {
      type: String,
      default: 'id'
    },
    currentRowKey: {
      type: [String, Number],
      default: null
    },
    rowStyle: {
      type: Object,
      default: () => ({})
    },
    cellClassName: {
      type: Function,
      default: null
    },
    headerCellClassName: {
      type: Function,
      default: null
    },
    rowClassName: {
      type: Function,
      default: null
    },
    context: {
      type: Object,
      default: null
    },
    showOverflowTooltip: {
      type: Boolean,
      default: false
    },
    lazy: {
      type: Boolean,
      default: false
    },
    load: {
      type: Function,
      default: null
    },
    treeProps: {
      type: Object,
      default: () => ({
        children: 'children',
        hasChildren: 'hasChildren'
      })
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    expandRowKeys: {
      type: Array,
      default: () => []
    },
		selectedRowsKey: {
      type: Array,
      default: () => []
    },
    sortOrders: {
      type: Array,
      default: () => ['ascending', 'descending']
    },
    sortable: {
      type: [Boolean, String],
      default: false
    },
    multiSort: {
      type: Boolean,
      default: false
    },
    sortBy: {
      type: String,
      default: null
    },
    sortMethod: {
      type: Function,
      default: null
    },
    filters: {
      type: Object,
      default: () => ({})
    },
    fixedHeader: {
      type: Boolean,
      default: true
    },
    isOperateBtn: {
      type: Function,
      default: null
    }
  },
  emits: [
    'select', 'select-all', 'selection-change',
    'cell-click', 'row-click', 'row-dblclick',
    'header-click', 'sort-change', 'filter-change',
    'current-change', 'expand-change', 'show-operate'
  ],
  methods: {
    addUnit
  },
  setup(props, { emit }) {
    const expandedKeys = ref([...props.expandRowKeys]);
    const selectedRows = ref([...props.selectedRowsKey]);
    const sortConditions = ref([]);

    // 当前高亮行
    const currentRow = ref(null);
		
		watch(
		  () => props.selectedRowsKey,
		  newVal => {
		    selectedRows.value = [...newVal];
		  }
		);

    watch(
      () => props.expandRowKeys,
      newVal => {
        expandedKeys.value = [...newVal];
      }
    );

    watch(
      () => props.currentRowKey,
      newVal => {
        const found = props.data.find(item => item[props.rowKey] === newVal);
        if (found) {
          currentRow.value = found;
        }
      }
    );
		
    // 过滤后的数据
    const filteredData = computed(() => {
      return props.data.filter(row => {
        return Object.keys(props.filters).every(key => {
          const filter = props.filters[key];
          if (!filter) return true;
          return row[key]?.toString().includes(filter.toString());
        });
      }).map((row, index) => {
				return {
					...row,
					rowIndex: index
				}
			});
    });

    // 排序后的数据
    const sortedData = computed(() => {
      if (!sortConditions.value.length) return filteredData.value;

      const data = [...filteredData.value];

      return data.sort((a, b) => {
        for (const condition of sortConditions.value) {
          const { field, order } = condition;
          let valA = a[field];
          let valB = b[field];

          if (props.sortMethod) {
            const result = props.sortMethod(a, b, field);
            if (result !== 0) return result * (order === 'ascending' ? 1 : -1);
          }

          if (valA < valB) return order === 'ascending' ? -1 : 1;
          if (valA > valB) return order === 'ascending' ? 1 : -1;
        }
        return 0;
      });
    });

    function handleRowClick(row) {
      if (props.highlightCurrentRow) {
        const oldRow = currentRow.value;
        currentRow.value = row;
        emit('current-change', row, oldRow);
      }
      emit('row-click', row);
    }

    function handleHeaderClick(column) {
      if (!column.sortable) return;

      const index = sortConditions.value.findIndex(c => c.field === column.key);
      let newOrder = 'ascending';

      if (index >= 0) {
        if (sortConditions.value[index].order === 'ascending') {
          newOrder = 'descending';
        } else {
          sortConditions.value.splice(index, 1);
          emit('sort-change', sortConditions.value);
          return;
        }
      }

      if (!props.multiSort) {
        sortConditions.value = [{ field: column.key, order: newOrder }];
      } else {
        if (index >= 0) {
          sortConditions.value[index].order = newOrder;
        } else {
          sortConditions.value.push({ field: column.key, order: newOrder });
        }
      }

      emit('sort-change', sortConditions.value);
    }

    function getSortIcon(field) {
      const cond = sortConditions.value.find(c => c.field === field);
      if (!cond) return '';
      return cond.order === 'ascending' ? '↑' : '↓';
    }

    function toggleSelect(row) {
      const index = selectedRows.value.findIndex(r => r[props.rowKey] === row[props.rowKey]);
      if (index >= 0) {
        selectedRows.value.splice(index, 1);
      } else {
        selectedRows.value.push(row);
      }
      emit('selection-change', selectedRows.value);
      emit('select', row);
    }

    function isSelected(row) {
      return selectedRows.value.some(r => r[props.rowKey] === row[props.rowKey]);
    }
		
		function toggleSelectAll() {
			if (isSelectedAll()) {
				selectedRows.value = []
			} else {
				selectedRows.value = sortedData.value
			}
			emit('selection-change', selectedRows.value);
		}
		
		function isSelectedAll() {
		  return selectedRows.value.length > 0 && selectedRows.value.length === props.data.length;
		}

    function toggleExpand(row) {
      const key = row[props.rowKey];
      const index = expandedKeys.value.indexOf(key);
      if (index === -1) {
        expandedKeys.value.push(key);
      } else {
        expandedKeys.value.splice(index, 1);
      }
      emit('expand-change', {
				expandedKeys: expandedKeys.value,
				key
			});
    }

    function isExpanded(row) {
      return expandedKeys.value.includes(row[props.rowKey]);
    }
		
		const isOperateArr = ref([])
		const showOperate = (row) => {
			if (isOperateArr.value.includes(row[props.rowKey])) {
				isOperateArr.value = isOperateArr.value.filter(item => item != row[props.rowKey])
			} else {
				isOperateArr.value.push(row[props.rowKey])
			}
		}
    return {
      currentRow,
      sortedData,
      expandedKeys,
      selectedRows,
      sortConditions,
      handleRowClick,
      handleHeaderClick,
      getSortIcon,
      toggleSelect,
      isSelected,
      toggleExpand,
      isExpanded,
			isOperateArr,
			showOperate,
			isSelectedAll,
			toggleSelectAll
    };
  }
};
</script>

<style lang="scss" scoped>
.u-table {
  width: 100%;
  overflow: auto;
}
.u-table-header {
  background-color: #f5f7fa;
}
.u-table-sticky {
  position: sticky;
  top: 0;
  z-index: 10;
}
.u-table-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  border-bottom: 1rpx solid #ebeef5;
}
.u-table-cell {
  flex: 1;
  display: flex;
  flex-direction: row;
  padding: 5px 4px;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.u-table-fixed-left {
  position: sticky;
  left: 0;
  z-index: 9;
}
.u-table-fixed-right {
  position: sticky;
  right: 0;
  z-index: 9;
}
.u-table-row-zebra {
  background-color: #fafafa;
}
.u-table-row-highlight {
  background-color: #f5f7fa;
}
.u-table-empty {
  text-align: center;
  padding: 20px;
  color: #999;
}
.u-text-left {
  text-align: left;
}
.u-text-center {
  text-align: center;
	justify-content: center;
}
.u-text-right {
  text-align: right;
}
.table-expand-td {
	margin: 0 auto;
}
.operate-more {
	position: absolute;
	height: 32px;
	bottom: -5px;
	right: 5px;
	// background-color: #3c9cff;
	padding: 2px;
	border-radius: 10px 0 0 10px;
	opacity: .8;
	&-icon {
		width: 24px;
		height: 24px;
	}
}
</style>
